package es.gesfutbol.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.criterion.Order;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import es.gesfutbol.dao.IArbitreDao;
import es.gesfutbol.dao.IEstadisticaArbitreDao;
import es.gesfutbol.dao.IJornadaDao;
import es.gesfutbol.dao.ILligaDao;
import es.gesfutbol.dao.IPartitDao;
import es.gesfutbol.dao.IPartitDeQuinielaDao;
import es.gesfutbol.domini.ETipusArbitre;
import es.gesfutbol.domini.implementacio.Arbitre;
import es.gesfutbol.domini.implementacio.EstadisticaArbitre;
import es.gesfutbol.domini.implementacio.IdEstadisticaArbitre;
import es.gesfutbol.domini.implementacio.Jornada;
import es.gesfutbol.domini.implementacio.Lliga;
import es.gesfutbol.domini.implementacio.Partit;
import es.gesfutbol.domini.implementacio.PartitDeQuiniela;
import es.gesfutbol.util.OrdenaPartitPerId;
import es.gesfutbol.web.backbean.ActualitzarJornada;

public class ActualitzarJornadaController extends MultiActionController{
	
	private IJornadaDao jornadaDao;
	
	private IPartitDao partitDao;
	
	private ILligaDao lligaDao;
	
	private IArbitreDao arbitreDao;
	
	private IEstadisticaArbitreDao estadisticaArbitreDao;
	
	private IPartitDeQuinielaDao partitDeQuinielaDao;

	public IArbitreDao getArbitreDao() {
		return arbitreDao;
	}

	public void setArbitreDao(IArbitreDao arbitreDao) {
		this.arbitreDao = arbitreDao;
	}
	
	public IJornadaDao getJornadaDao() {
		return jornadaDao;
	}

	public void setJornadaDao(IJornadaDao jornadaDao) {
		this.jornadaDao = jornadaDao;
	}
	
	public IPartitDao getPartitDao() {
		return partitDao;
	}

	public void setPartitDao(IPartitDao partitDao) {
		this.partitDao =partitDao;
	}
	
	public ILligaDao getLligaDao() {
		return lligaDao;
	}

	public void setLligaDao(ILligaDao lligaDao) {
		this.lligaDao = lligaDao;
	}
	
	public IEstadisticaArbitreDao getEstadisticaArbitreDao() {
		return estadisticaArbitreDao;
	}

	public void setEstadisticaArbitreDao(IEstadisticaArbitreDao estadisticaArbitreDao) {
		this.estadisticaArbitreDao = estadisticaArbitreDao;
	}
	
	public IPartitDeQuinielaDao getPartitDeQuinielaDao(){
		return partitDeQuinielaDao;
	}
	
	public void setPartitDeQuinielaDao(IPartitDeQuinielaDao partitDeQuinielaDao){
		this.partitDeQuinielaDao = partitDeQuinielaDao;
	}
	
	
	public ModelAndView init(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		List<Jornada> jornadesActives = jornadaDao.findActives();
		jornadesActives = jornadaDao.deproxyLligues(jornadesActives);
		
		List<Jornada> llistatJornades = jornadaDao.findAll(Order.asc("data"));
		llistatJornades = jornadaDao.deproxyLligues(llistatJornades);

		ModelMap modelMap = new ModelMap();
		modelMap.put("jornadesActives", jornadesActives);		
		modelMap.put("llistatJornades", llistatJornades);
		return new ModelAndView("administracion/actualitzarJornades", modelMap);		
	}
	
//	// It will be just called when some validation or binding Exception occurs
//	// Otherwise, Spring will bypass it
	public ModelAndView hanldeBindException(HttpServletRequest request, HttpServletResponse response, ServletRequestBindingException bindingException) {
	    
		BindException bindException = (BindException) bindingException.getRootCause();
		BindingResult bindingResult = (BindingResult) bindException.getModel().get(BindingResult.MODEL_KEY_PREFIX + "command");
		String error = bindingResult.getFieldError().getDefaultMessage();
		
		ActualitzarJornada actJornada = (ActualitzarJornada)bindingResult.getTarget();		
				
		Long idJornada = actJornada.getIdJornada();
		
		Long idPartit = actJornada.getIdPartit();
			
		String sURL = "redirect:updatePartit.htm?";
		String sJornada = "idJornada=" + idJornada.toString();
		String sPartit = "&idPartit=" + idPartit.toString();
		String sError = "&idError=" + error.toString();
		return new ModelAndView(sURL+sJornada+sPartit+sError);
		
	}
	
	public ModelAndView viewPartits(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		Long idJornada = Long.parseLong(request.getParameter("idJornada"));
		Jornada jornada = jornadaDao.findById(idJornada);
		jornada = jornadaDao.deproxy(jornada);
		
		Long idLliga = jornada.getLliga().getIdLliga();
		Lliga lliga = lligaDao.findById(idLliga);
		jornada.setLliga(lliga);
		
		Set<Partit> partits = jornada.getPartits();
		partits = partitDao.deproxylist(partits);
		
		List<Partit> lPartits = new ArrayList<Partit>(partits);
		Collections.sort(lPartits, new OrdenaPartitPerId());
		
				
		ModelMap modelMap = new ModelMap();
		modelMap.put("jornada", jornada);		
		modelMap.put("llistatPartits", lPartits);
		return new ModelAndView("administracion/actualitzarPartits", modelMap);		
	}
	
	public ModelAndView updatePartit(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		String error = request.getParameter("idError");

		Long idJornada = Long.parseLong(request.getParameter("idJornada"));
		Jornada jornada = jornadaDao.findById(idJornada);
		jornada = jornadaDao.deproxy(jornada);
		
		Long idLliga = jornada.getLliga().getIdLliga();
		Lliga lliga = lligaDao.findById(idLliga);
		jornada.setLliga(lliga);
		
		Long idPartit = Long.parseLong(request.getParameter("idPartit"));
		Partit partit = partitDao.findById(idPartit);
		partit = partitDao.deproxylock(partit);
		
		List<Arbitre> arbitres = arbitreDao.findAll(Order.asc("nom"));
		
		ActualitzarJornada actualitzarJornada = new ActualitzarJornada();
		actualitzarJornada.setGolsLocal(partit.getGolsLocal());
		actualitzarJornada.setGolsVisitant(partit.getGolsVisitant());
		
		//Busquem l'arbitre principal del Partit
		
		//Arbitre arbitre = new Arbitre();		
		List<EstadisticaArbitre> listEstadisticaArbitre = estadisticaArbitreDao.findByIdPartitDeproxy(idPartit);
		if(listEstadisticaArbitre!=null){			
			Iterator<EstadisticaArbitre> itEstArb = listEstadisticaArbitre.iterator();
			while(itEstArb.hasNext()){									
					EstadisticaArbitre estadisticaArbitre = itEstArb.next();
					if(estadisticaArbitre.getRol()==ETipusArbitre.PRINCIPAL){
						Long idArbitre = estadisticaArbitre.getId().getArbitre().getIdArbitre();
						actualitzarJornada.setIdArbitre(idArbitre);
					}					
			}
		}
			
		ModelMap modelMap = new ModelMap();
		modelMap.put("jornada", jornada);
		modelMap.put("error", error);
		modelMap.put("actualitzarJornada", actualitzarJornada);
		modelMap.put("partit", partit);
		modelMap.put("llistatArbitres", arbitres);
		return new ModelAndView("administracion/actualitzarResultats", modelMap);		
	}
	
	public ModelAndView addOrUpdate(HttpServletRequest request,
			HttpServletResponse response, ActualitzarJornada actualitzarJornada){
		
		Long idPartit = actualitzarJornada.getIdPartit();		
		Partit partit = partitDao.findById(idPartit);
	
		Integer golsLocal = actualitzarJornada.getGolsLocal(); 					
		Integer golsVisitant = actualitzarJornada.getGolsVisitant();		
		partit.setGolsLocal(golsLocal);
		partit.setGolsVisitant(golsVisitant);
		
		Long idJornada = actualitzarJornada.getIdJornada();
		
		Long idArbitre = actualitzarJornada.getIdArbitre();
		Arbitre arbitre = arbitreDao.findById(idArbitre);
		
		//Fixem l'id de EstadisticaArbitre amb el partit i l'arbitre
		IdEstadisticaArbitre idEstadisticaArbitre = new IdEstadisticaArbitre();
		idEstadisticaArbitre.setArbitre(arbitre);
		idEstadisticaArbitre.setPartit(partit);
		
		EstadisticaArbitre estadisticaArbitre = new EstadisticaArbitre();
		estadisticaArbitre.setId(idEstadisticaArbitre);
		estadisticaArbitre.setRol(ETipusArbitre.PRINCIPAL);
		
		//salvem el resultat del partit
		partitDao.save(partit);
		//salvem l'arbitre del partit
		estadisticaArbitreDao.saveOrUpdate(estadisticaArbitre);
		//actualitzem resultat de partitDeQuiniela si el partit pertany a una quiniela
		PartitDeQuiniela partitDeQuiniela = partitDeQuinielaDao.findByIdPartit(idPartit);
		if(partitDeQuiniela!=null){
			if(partit.getGolsLocal() > partit.getGolsVisitant())	partitDeQuiniela.setResultat("1");
			if(partit.getGolsLocal() == partit.getGolsVisitant())	partitDeQuiniela.setResultat("X");
			if(partit.getGolsLocal() < partit.getGolsVisitant())	partitDeQuiniela.setResultat("2");
			partitDeQuinielaDao.save(partitDeQuiniela);
		}		
		
		String sURL = "redirect:viewPartits.htm?idJornada=";
		String sJornada = idJornada.toString();

		return new ModelAndView(sURL+sJornada);
		
	}

}
